<script setup>
import { ref, computed, getCurrentInstance, onMounted, watch } from 'vue'
import { selectorRectInfo } from '@/common/utils'

const props = defineProps({
  // 歌词数据
  list: {
    type: Array,
    default: () => [],
  },
  // 当前音频的播放时间
  currentTime: {
    type: Number,
    default: 0,
  },
  // 是否显示加载
  loading: {
    type: Boolean,
    default: false,
  },
})

// 事件
const emit = defineEmits(['seek'])

// 获取组件实例
const instance = getCurrentInstance()

// 歌词容器高度
const lrcHeight = ref(0)
// 歌词居中高度
const centerTop = ref(0)
// 获取歌词滚动高度
const scrollTop = ref(0)

// 当前歌词索引
const currentIndex = computed(() => {
  const currentIndexInRange = props.list.findIndex((item, index) => {
    if (index < props.list.length - 1) {
      // 防止数组越界
      const nextTime = props.list[index + 1].time
      const currentTime = props.currentTime * 1000
      return (
        currentTime < item.time ||
        (currentTime >= item.time && currentTime < nextTime)
      )
    }
    return index // 如果已经是最后一项，返回false，后续不会再检查
  })
  // 如果没有找到符合条件的歌词，返回-1或其他默认值
  return currentIndexInRange !== -1 ? currentIndexInRange : -1
})

// 歌词高亮项高度
const setLrcHeight = async (index) => {
  // 获取歌词容器高度
  const lrc = await selectorRectInfo('.song-lrc', instance)
  // 获取当前歌词项对应的DOM元素信息
  const lrcItem = await selectorRectInfo('.song-lrc-item', instance)

  if (lrc?.height) {
    // 赋值高度
    lrcHeight.value = lrc.height
  }
  // 判断歌词项有高度
  if (lrcItem?.height) {
    // 居中高度
    centerTop.value = (lrcHeight.value - lrcItem.height) / 2
    // 滚动距离
    scrollTop.value = index * lrcItem.height - centerTop.value
  }
}

// 点击歌词项跳转到对应歌曲位置
const changeLrcItem = (time) => {
  emit('seek', parseInt((time / 1000).toFixed(3)))
}

watch(
  () => props.currentTime,
  (newTime) => {
    setLrcHeight(currentIndex.value)
  }
)

onMounted(() => {
  // 设置高度
  setLrcHeight(currentIndex.value)
})
</script>

<template>
  <view class="song-lrc">
    <template v-if="lrcHeight >= 50">
      <ty-loading
        type="row"
        text="歌词加载中"
        color="#FFFFFF"
        icon-size="40"
        background-color=""
        :isFixed="false"
        v-if="loading"
      ></ty-loading>
      <view
        class="song-lrc-main"
        v-else-if="list.length > 0"
      >
        <scroll-view
          class="song-lrc-scroll"
          scroll-y
          scroll-with-animation
          :scroll-top="scrollTop"
        >
          <view
            class="song-lrc-list"
            :style="{ paddingBottom: `${centerTop}px` }"
          >
            <view
              class="song-lrc-item"
              v-for="(item, index) in list"
              :key="index"
              :class="{ active: index === currentIndex || list.length <= 1 }"
              @click="changeLrcItem(item.time)"
            >
              <text class="song-lrc-text">{{ item.text }}</text>
            </view>
          </view>
        </scroll-view>
      </view>
      <view
        class="song-lrc-noList"
        v-else
      >
        <text class="song-lrc-text">暂无歌词~</text>
      </view>
    </template>
  </view>
</template>

<style lang="scss" scoped>
.song-lrc,
.song-lrc-scroll {
  overflow: hidden;
  width: 100%;
  height: 100%;
}

.song-lrc {
  &-main {
    display: flex;
    flex-direction: column;
    text-align: center;
    transition: all 0.3s cubic-bezier(0.4, 0, 1, 1);
    height: 100%;
  }
  &-text {
    color: $u-bg-color-inverse;
    font-size: 30rpx;
  }
  &-item {
    transition: all 0.3s cubic-bezier(0.4, 0, 1, 1);
    padding: $ty-md-padding 0;
    opacity: 0.5;
    filter: blur(3rpx);
    white-space: nowrap;
    overflow: hidden;
    &.active {
      transform: scale(1.01);
      opacity: 1;
      filter: blur(0);
      .song-lrc-text {
        background-image: linear-gradient(
          to bottom,
          $u-bg-color-inverse,
          $u-type-primary
        );
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
      }
    }
  }
  &-noList {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style>
